#include <iostream>

#include "formula_callable.hpp"
#include "raster.hpp"
#include "resource.hpp"
#include "wml_node.hpp"
#include "wml_utils.hpp"

namespace {
std::map<std::string, resource_ptr> resources;
std::vector<const_resource_ptr> global_resources;
}

void resource::init(wml::const_node_ptr node)
{
	wml::node::const_child_iterator i1 = node->begin_child("resource");
	wml::node::const_child_iterator i2 = node->end_child("resource");
	for(; i1 != i2; ++i1) {
		resource_ptr new_resource(new resource(i1->second));
		resources[new_resource->id()] = new_resource;
		if(new_resource->global_) {
			global_resources.push_back(new_resource);
		}
	}
}

const std::vector<const_resource_ptr>& resource::get_global_resources()
{
	return global_resources;
}

const_resource_ptr resource::get(const std::string& key)
{
	return resources[key];
}

resource::resource(wml::const_node_ptr node)
  : id_(node->attr("id")), item_type_(item_type::get(node->attr("produces"))),
    input_item_type_(item_type::get(node->attr("input"))),
    specialization_(node->attr("specialization")),
    improvement_(node->attr("improvement")),
    level_up_(game_logic::formula::create_optional_formula(node->attr("level_up"))),
    production_rate_(wml::get_int(node, "production_rate", 1)),
    weather_bonus_(game_logic::formula::create_optional_formula(node->attr("weather_bonus"))),
	min_quality_for_texture_(wml::get_int(node, "min_quality_for_image", -1)),
    global_(wml::get_bool(node, "global", false))
{
	if(node->has_attr("image")) {
		texture_ = graphics::texture::get(node->attr("image"));
	}

	SDL_Color col = {wml::get_int(node, "red"), wml::get_int(node, "green"), wml::get_int(node, "blue"), 0xFF};
	color_ = col;
	if(!item_type_) {
		std::cerr << "invalid item type: '" << node->attr("produces") << "'\n";
		throw parse_error();
	}
}

const std::string& resource::uses() const
{
	if(input_item_type_) {
		return input_item_type_->id();
	} else {
		static const std::string empty_string;
		return empty_string;
	}
}

item resource::produce() const
{
	return item(item_type_);
}

int resource::weather_bonus(int weather, int river) const
{
	if(!weather_bonus_) {
		return 0;
	}

	game_logic::map_formula_callable callable;
	callable.add("weather", variant(weather));
	callable.add("river", variant(river));
	const int result = weather_bonus_->execute(callable).as_int();
	return result;
}

const_item_type_ptr resource::input() const
{
	return input_item_type_;
}

void resource::draw(int quality, int x, int y) const
{
	if(texture_.valid() && quality >= min_quality_for_texture_) {
		graphics::blit_texture(texture_, x, y);
	}
}
